package com.sinodata.bsm.cicp.util.telnet;

import java.io.File;
import java.io.IOException;

import org.apache.log4j.Logger;

import ch.ethz.ssh2.Connection;

import com.sinodata.bsm.cicp.util.ProtocolParameterUtil;
import com.sinodata.bsm.common.constants.ProtocolConstants;
import com.sinodata.bsm.common.vo.ProtocolParameter;

/**
 * 
 * <p>
 * Description: 以ganymed框架重写的SSH2连接
 * </p>
 *
 * @author wangyazhou
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * Mar 28, 2011 10:06:53 AM wangyz         1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class EthzSSH {

    private static final Logger logger = Logger.getLogger(EthzSSH.class);

    private Connection conn = null;
    protected boolean isValid = true;

    public EthzSSH() {

    }

    /**
     * 登录 并做权限认证
     * @param host
     * @param port
     * @param user
     * @param pwd
     * @throws Exception
     */
    public void login(String host, int port, String user, String pwd) throws Exception {

        ProtocolParameter protocolParameter = ProtocolParameterUtil.getHostValue(host);
        conn = new Connection(host.split(":")[0], port); //只有当连接时截取下实际的ip
        conn.connect();

        logger.info("[TIP]\tList Of Available Auth Methods:");
        String[] retVals = conn.getRemainingAuthMethods(user);
        for (String str : retVals) {
            logger.debug(str);
        }

        String authType = "password";
        if (protocolParameter != null) {
            authType = protocolParameter.getSshdAuthType();
        }
        if (authType == null || authType.length() < 1 || ProtocolConstants.SSHD_PASSWORD.equals(authType)) {
            boolean isAuthenticated = conn.authenticateWithPassword(user, pwd);
            if (isAuthenticated == false) {
                throw new IOException("[TIP]\tAuthentication failed With User:" + user + " Pwd:" + pwd);
            }
        }

        if (ProtocolConstants.SSHD_PUBLICKEY.equals(authType)) {
            String fileName = protocolParameter.getSshdAuthFile();
            String file = "";
            if (fileName != null && fileName.length() > 1) {
                file = fileName.replace("/", File.separator);
            }
            File keyfile = new File(file); // or "~/.ssh/id_dsa"
            boolean isAuthenticated = conn.authenticateWithPublicKey(user, keyfile, pwd);
            if (isAuthenticated == false) {
                throw new IOException("[TIP]\tAuthentication Failed With Public Key:" + keyfile);
            }
            logger.info("[TIP]\t" + host + "--" + file);
        }
        logger.info("[TIP]\tCreate A New SSH2 Connection With:" + host + " -- " + user);
    }

    /**
     * SSH2认证登录  测试用
     * @param host
     * @param port
     * @param user
     * @param auth:认证方式 passward  publickey
     * @param pwd :passward时的密码
     * @param keyfile:publickey时的公共密钥路径
     */
    public void login(String host, int port, String user, String auth, String pwd, String fileName) throws Exception {
        logger.info(host + "--" + user + "--" + auth + "--" + pwd + "--" + fileName);
        conn = new Connection(host, port);
        conn.connect();

        logger.info("[TIP]\tList Of Available Auth Methods:");

        logger.info("public key 登录");
        String[] retVals = conn.getRemainingAuthMethods(user);
        for (String str : retVals) {
            logger.debug(str);
        }
        if (ProtocolConstants.SSHD_PASSWORD.equals(auth)) {
            boolean isAuthenticated = conn.authenticateWithPassword(user, pwd);
            if (isAuthenticated == false) {
                throw new IOException("[TIP]\tAuthentication failed With User:" + user + " Pwd:" + pwd);
            }
        } else if (ProtocolConstants.SSHD_PUBLICKEY.equals(auth)) {
            String file = "";
            if (fileName != null && fileName.length() > 1) {
                file = fileName.replace("/", File.separator);
            }
            //File keyfile1 = new File(file); // or "~/.ssh/id_dsa"
            File keyfile = new File(file); // or "~/.ssh/id_dsa"
            boolean isAuthenticated = conn.authenticateWithPublicKey(user, keyfile, pwd);
            if (isAuthenticated == false) {
                throw new IOException("[TIP]\tAuthentication Failed With Public Key:" + keyfile);
            }
            logger.info("[TIP]\t" + host + "--" + file);
        }
        logger.info("[TIP]\tCreate A New SSH2 Connection With:" + host + " -- " + user);
    }

    /**
     * 释放连接 不是放回连接池
     */
    public void disconn() {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (Exception e) {
            logger.error("failed to close conn and session", e);
        }

    }

    public Connection getConn() {
        return conn;
    }

    public void setConn(Connection conn) {
        this.conn = conn;
    }

    public boolean getValid() {
        return isValid;
    }

    public void setValid(boolean isValid) {
        this.isValid = isValid;
    }

}
